mod user;
mod event;
mod guild;

use serde::{Deserialize, Serialize};
use serde_json::Value;
use sqlx::FromRow;
use uuid::Uuid;

/// # 频道
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriChannel {
    pub id: String,    //频道 ID
    pub r#type: SatoriChannelType,    //频道类型
    pub name: Option<String>,    //频道名称
    pub parent_id: Option<String>,    //父频道 ID
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub enum SatoriChannelType {
    #[default]
    TEXT = 0,    //文本频道
    DIRECT = 1,    //私聊频道
    CATEGORY = 2,    //分类频道
    VOICE = 3,    //语音频道
}

/// # 群组
#[derive(Debug, Clone, Serialize, Deserialize, FromRow, Default)]
pub struct SatoriGuild {
    id: String,    //群组 ID
    name: Option<String>,    //群组名称
    avatar: Option<String>,    //群组头像
}

/// # 群组成员
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriGuildMember {
    pub user: Option<SatoriUser>,    //用户对象
    pub nick: Option<String>,    //用户在群组中的名称
    pub avatar: Option<String>,    //用户在群组中的头像
    pub joined_at: Option<i64>,    //加入时间
}

/// # 群组角色
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriGuildRole {
    id: String,    //角色 ID
    name: Option<String>,    //角色名称
}

/// # 交互
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriArgv {
    name: String,    //指令名称
    arguments: Vec<Value>,    //参数
    options: Value,    //选项
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriButton {
    id: String,    //按钮 ID
}

/// # 登录信息
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriLogin {
    adapter: String,    //适配器名称
    platform: Option<String>,    //平台名称
    user: Option<SatoriUser>,    //用户对象
    status: Option<SatoriLoginStatus>,    //登录状态
    features: Option<Vec<String>>,    //平台特性 列表
    proxy_urls: Option<Vec<String>>,    //代理路由 列表
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub enum SatoriLoginStatus {
    #[default]
    OFFLINE = 0,    //离线
    ONLINE = 1,    //在线
    CONNECT = 2,    //连接中
    DISCONNECT = 3,    //断开连接
    RECONNECT = 4,    //重新连接
}

/// # 消息
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SatoriMessage {
    pub id: String,    //消息 ID
    pub content: String,    //消息内容
    pub channel: Option<SatoriChannel>,    //频道对象
    pub guild: Option<SatoriGuild>,    //群组对象
    pub member: Option<SatoriGuildMember>,    //群组成员对象
    pub user: Option<SatoriUser>,    //用户对象
    pub created_at: Option<i64>,    //消息发送的时间戳
    pub updated_at: Option<i64>,    //消息修改的时间戳
}

/// # 用户
/// [1] `name` 和 `nick` 字段的区别
///
/// ```
/// 这两个字段都可以用于标识用户。在一些平台上 (例如 Telegram)，一个用户存在多种不同概念的名称，因此 SDK 可以同时设置这两个字段。而另一些平台可能不存在这两个概念的对立关系，此时 SDK 只需要根据语义设置 name 或 nick 中的一个即可。
///
/// 在应用层实现上，nick 的优先级高于 name，因为昵称更容易被用户识别和理解。如果你正在开发基于 Satori 协议的客户端，在用户名的显示上应当优先使用 nick 字段，只有当 nick 为空时才使用 name 字段。
/// ```
#[derive(Debug, Clone, Serialize, Deserialize, FromRow, Default)]
pub struct SatoriUser {
    pub id: Uuid,    //用户 ID
    pub name: Option<String>,    //用户名称[1]
    pub nick: Option<String>,    //用户昵称[1]
    pub avatar: Option<String>,    //用户头像链接
    pub is_bot: Option<bool>,    //是否为机器人
}

/// # API - Direction
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub enum SatoriDirection {
    Before, //向前获取数据，此时 prev 和 next 相同，均表示上一页的令牌。
    #[default]
    After, //向后获取数据，此时 prev 和 next 相同，均表示下一页的令牌。
    Around, //向两侧获取数据，此时 prev 表示上一页的令牌，next 表示下一页的令牌。
}

/// # API - Order
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub enum SatoriOrder {
    #[default]
    Asc, //升序排列。
    Desc, //降序排列。
}